package mobi.pooper;

import static mobi.pooper.Constants.*;

import java.io.BufferedReader;
import java.io.IOException;

import mobi.pooper.db.IPicsDbAdapter;
import mobi.pooper.pictures.Picture;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.actions.RotateTo;
import com.badlogic.gdx.scenes.scene2d.actions.ScaleTo;
import com.badlogic.gdx.scenes.scene2d.actions.Sequence;
import com.badlogic.gdx.scenes.scene2d.ui.Align;
import com.badlogic.gdx.scenes.scene2d.ui.ClickListener;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.utils.Scaling;

public class BrowserScreen implements Screen {

	protected static final String TAG = BrowserScreen.class.getSimpleName();

	private static final String TASK_TEXT = "taskText";

	private static final String TASK_IMAGE = "taskImage";

	private Pooper pooper;
	private GameStage stage;

	private Picture[] pictures;
	private int currentPictureIndex = 0;
	private Sound sound;

	private BitmapFont taskTextFont;
	
	private Label taskTextLabel;
	private Image taskImage;
	private Texture taskTexture;
	
	private ClickListener leftClick = new ClickListener(){
		@Override
		public void click(Actor actor, float x, float y) {
			try {
				updateView(currentPictureIndex - 1);
				actor.action(Sequence.$(ScaleTo.$(1.5f, 1.5f, 0.5f), ScaleTo.$(1, 1, 0.5f)));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	};

	private ClickListener rightClick = new ClickListener(){
		@Override
		public void click(Actor actor, float x, float y) {
			try {
				updateView(currentPictureIndex + 1);
				actor.action(Sequence.$(ScaleTo.$(1.5f, 1.5f, 0.5f), ScaleTo.$(1, 1, 0.5f)));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	};

	private ClickListener currentImageClick = new ClickListener(){
		@Override
		public void click(Actor actor, float x, float y) {
			if(sound != null) {
				sound.play();
				actor.action(Sequence.$(RotateTo.$(15, 0.3f), RotateTo.$(-15, 0.3f), RotateTo.$(0, 0.3f)));
			}
		}
	};

	public BrowserScreen(Pooper pooper) throws IOException {
		this.pooper = pooper;

		taskTextFont = new BitmapFont(Gdx.files.internal("data/fonts/rus.fnt"), false);

		stage = new GameStage(pooper, NATIVE_WIDTH, NATIVE_HEIGHT, false);
		Gdx.input.setInputProcessor(stage);
		
		pictures = loadPictures();
		placeControls();

		updateView(currentPictureIndex);
	}

	private Picture[] loadPictures() {
		IPicsDbAdapter dba = ((IPooperApplication)Gdx.app).getPicsDbAdapter();
		dba.open();
		Picture[] retval = dba.getAllItems();
		dba.close();

		return retval;
	}
	
	private void placeControls() {
		
		Texture leftTexture = new Texture(Gdx.files.internal("data/images/arrow_left.png"));
		Texture rightTexture = new Texture(Gdx.files.internal("data/images/arrow_right.png"));
		
		Image leftImage = new Image(leftTexture, Scaling.fit);
		Image rightImage = new Image(rightTexture, Scaling.fit); 

		leftImage.x = leftTexture.getWidth();
		leftImage.y = leftTexture.getHeight();
		rightImage.x = NATIVE_WIDTH - rightTexture.getWidth() * 2;
		rightImage.y = rightTexture.getHeight();
		
		leftImage.setClickListener(leftClick);
		rightImage.setClickListener(rightClick);
		
		stage.addActor(leftImage);
		stage.addActor(rightImage);
	}

	private void updateView(int index) throws IOException{
		
		if(index < 0 || index > (pictures.length - 1)) return;

		currentPictureIndex = index;
		Picture currentPicture = pictures[index];
		
		if(taskTextLabel == null){
			taskTextLabel = new Label("Пусто", new Label.LabelStyle(taskTextFont, Color.WHITE), TASK_TEXT);
			stage.addActor(taskTextLabel);
		}
		updateTaskText(taskTextLabel, index);
		
		if(taskImage != null){
			stage.removeActor(taskImage);
			taskTexture.dispose();
		}
		updatePictureAndSound(pictures[index]);
	}

	private void updateTaskText(Label lbl, int index) throws IOException {
		CharSequence taskText = getTaskText(pictures[index]);
		
		lbl.setText(taskText);
		lbl.x = NATIVE_WIDTH / 2 - taskTextFont.getBounds(taskText).width / 2;
		lbl.y = NATIVE_HEIGHT * 3 / 4;
	}

	private CharSequence getTaskText(Picture pic) throws IOException {

		FileHandle taskFile = Gdx.files.internal(TASKS_PATH + "/" + pic.getName() + ".txt");
		BufferedReader br = new BufferedReader(taskFile.reader());
		CharSequence retval = br.readLine();

		Gdx.app.debug(TAG, "Current task text = " + retval);
		return retval;
	}


	private void updatePictureAndSound(Picture pic){

		String name = pic.getName();
		
		FileHandle soundFile = Gdx.files.internal(TASKS_PATH + "/" + name + ".mp3");
		if(soundFile.exists()){
			sound = Gdx.audio.newSound(soundFile);
		}else{
			sound = Gdx.audio.newSound(Gdx.files.internal(NO_SOUND_FILE));
		}
		
		taskTexture = new Texture(Gdx.files.internal(TASKS_PATH + "/" + name + ".jpg"));

		taskImage = new Image(taskTexture, Scaling.fit, Align.CENTER, TASK_IMAGE);
		taskImage.x = NATIVE_WIDTH / 2 - PICTURE_WIDTH;
		taskImage.y = NATIVE_HEIGHT / 4;
		taskImage.originX = PICTURE_WIDTH;
		taskImage.originY = PICTURE_HEIGHT;
		taskImage.width = PICTURE_WIDTH * 2;
		taskImage.height = PICTURE_HEIGHT * 2;
		
		taskImage.setClickListener(currentImageClick);

		stage.addActor(taskImage);
		Gdx.input.setInputProcessor(stage);
	}

	@Override
	public void dispose() {
		stage.dispose();
	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub

	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub

	}

	@Override
	public void render(float arg0) {
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		stage.act(Gdx.graphics.getDeltaTime());
		stage.draw();
	}

	@Override
	public void resize(int width, int height) {
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub

	}

	@Override
	public void show() {
		// TODO Auto-generated method stub

	}
}
